Colin Walters [Sun, 6 Apr 2025 21:24:26 +0000 (17:24 -0400)]
sysroot: Detect early on when /boot is on vfat
We do want to support this (as part of supporing the
Boot Loader Spec) but because we use symlinks in `/boot`,
can't yet.
Error out very early on consistently if we detect
vfat for /boot, but also add a member variable to keep track
of this in preparation for supporting it.
Colin Walters [Wed, 30 Apr 2025 12:30:05 +0000 (08:30 -0400)]
tests/prune: Ensure /boot is big enough for 3 bootdata
The size of kernel+initramfs (bootdata) for FCOS has crept up
enough that it's *always* triggering this path, which perturbs
the test into incorrectly triggering early prune.
If we detect that /boot is too small, allocate a new loopback-mounted
copy.
Basically when run via a non-static prepareroot we create
`/run/ostree-booted` consistently in the initramfs,
using the kernel argument presence as source of truth.
But for the static prepareroot, the generator checked
the kernel argument, and had a fallback of creating it.
Except that's busted in the case of running in a
container, where with many runtimes we still
default to seeing the host's commandline (which
is basically wrong...but fixing that requires a
userspace virtualizer/interceptor for `/proc`
so it's not commonly done).
This should fix the static prepareroot path
by detecting the case where we're compiled
with a static prepareroot, and if so we then
hardcode creating the `/run/ostree-booted`
file in the generator. I think basically
everyone who is compiling ostree with
a static prepareroot *and* including it
in their filesystem trees can be pretty
much guaranteed to be actually using it.
Colin Walters [Tue, 8 Apr 2025 19:52:11 +0000 (19:52 +0000)]
sysroot: Load bootloader configs via boot_fd
This was a general principle cleanup, preparation
for handling VFAT for /boot for systemd-boot/BLS
support.
However I ran into an ugly corner case in our
unit tests that pointed at a sysroot without a
boot directory. The previous logic handled
ENOENT for boot/loader but not /boot.
Continue to cope with that degenerate situation.
Colin Walters [Thu, 20 Mar 2025 16:47:48 +0000 (12:47 -0400)]
unlock: Use deployment backing dir
Closes: https://github.com/ostreedev/ostree/issues/3391
Basically it's not uncommon to make `/var/tmp` a separate
partition, but this constrains the amount of data that
can be written to `/usr` when unlocking.
Change things here to write to the deployment's backing
dir which is part of the same rootfs as the storage
and is lifecycle bound to the deployment, ensuring
it gets GC'd.
Daiki Ueno [Mon, 24 Mar 2025 12:25:12 +0000 (21:25 +0900)]
Fix build error with --with-ed25519-libsodium and --with-openssl
While libotcore can be configured with those options individually, the
latter is always required for OpenSSL's EVP functions. This splits the
ifdefs to accommodate that.
Colin Walters [Fri, 21 Mar 2025 12:11:50 +0000 (08:11 -0400)]
tests/auto-prune: Don't go negative
- First I kept wondering what the magic of 10000 was here before
looking above and noticing it matched the number of dtb files.
Make a shared variable so the connection is more obvious
- Next, I *believe* the intention of this test was to test
the edge case of bytes vs blocks, but we ended up subtracting
blocks and I think recent FCOS images happened to get small
enough that we started going negative here.
Fix this to convert the bytes into blocks.
sign: Support generic "spki" type of commit signatures
The current "ed25519" signing type assumes raw Ed25519 key format for
both public and private keys. This patch generalizes it by adding a
new signature type "spki" which uses the X.509 SubjectPublicKeyInfo
format for public keys. Keys in this format can easily be created with
openssl tools and provide crypto agility[1] as the format embeds
algorithm identifier.
The supposed use-case of this feature is to attach multiple signatures
with different algorithms to a single commit, so even if an algorithm
turned vulnerable, the signatures made with other algorithms can still
be used as a fallback. For instance, signer can create an Ed25519
signature along with a quantum-resistent ML-DSA signature.
The following are a couple of implementation notes:
- The private keys shall be stored in the PKCS#8 format, though future
extensions may support other format such as opaque key handles on a
hardware token.
- The "spki" signature type prefers the keys to be encoded in the PEM
format on disk, while it still accepts base64 encoded keys when given
through the command-line.
Daiki Ueno [Fri, 9 Aug 2024 05:54:27 +0000 (14:54 +0900)]
sign: Add PEM reading facility
This adds a new class OstreePemReader, which reads PEM blocks from an
input stream. This would be useful for the "x509" signing backend, as
the keys are typically stored in the PEM format.
Daiki Ueno [Sun, 11 Aug 2024 06:08:12 +0000 (15:08 +0900)]
sign: Factor out logic to read key blobs
This defines a new interface OstreeBlobReader, which encapsulates the
key file parsing logic. This would make it easy to support custom file
formats such as PEM.
Use fsfreeze_thaw_cycle(/boot) instead of fsync(/boot)
Grub doesn't support replaying XFS journal, so when using
XFS for /boot, fsync() or syncfs() are not enough and can
leave the system in an unbootable state.
Jonathan Lebon [Fri, 7 Mar 2025 21:49:27 +0000 (16:49 -0500)]
boot: Drop ostree-finalize-staged.path
This effectively reverts ac1a919f ("boot: Add
ostree-finalize-staged.path").
A bug came in on the OCP side that demonstrates that the way things are
setup right now is racy. If a reboot is triggered quickly after staging
a deployment, the whole pipeline of:
- ostree-finalize-staged.path, which triggers
- ostree-finalize-staged.service, which triggers
- ostree-finalize-staged-hold.service,
may not fully have happened before systemd isolates to `reboot.target`
which will want to kill all pending jobs.
Just directly starting the systemd unit is less elegant but much more
explicit and gets rid of any possible race because it's directly part of
the staging operation.
Colin Walters [Tue, 25 Feb 2025 19:14:19 +0000 (14:14 -0500)]
core: canonicalize bare-user xattrs
Previously we were erroring out if xattrs were provided in
non-canonical (e.g. unsorted) form all the way down to just
the bare-user path. But for archive repos and dirmeta we
canonicalized.
Canonicalize bare-user xattrs on both read and write consistently
instead of erroring.
Alyssa Ross [Fri, 14 Feb 2025 11:26:11 +0000 (12:26 +0100)]
libostree: add private dependencies to pkg-config
This makes it possible to use pkg-config to link against libostree as
a static library. Unlike shared libraries, static libraries don't
encode their dependencies in the library file, so we have to
communicate them via pkg-config.
fossdd [Mon, 27 Jan 2025 16:49:39 +0000 (17:49 +0100)]
libotutil: Remove redundant import of prctl.h
sys/prctl.h already provides prctl.h and adding both imports fails on
musl libc:
/usr/include/sys/prctl.h:88:8: error: redefinition of 'struct prctl_mm_map'
88 | struct prctl_mm_map {
| ^~~~~~~~~~~~
In file included from src/libotutil/ot-unix-utils.c:33:
/usr/include/linux/prctl.h:134:8: note: originally defined here
134 | struct prctl_mm_map {
| ^~~~~~~~~~~~
Basically our composefs enablement flag has long had a tension between
trying to do two things:
- Enable generating the composefs blob (at deployment time)
- Enable at runtime in prepare-root
And we've hit issues in "ratcheting" enabling composefs
across upgrades because of this.
This change builds on the previous one, and now it's really
simple to talk about:
- If composefs is enabled at build time, we *always*
generate a composefs blob at deplyment time
- Configuring the prepare-root config now mostly
only affects the runtime state.
There is one detail though: in order to handle the
verity requirement at deploy time, we do still parse
the config then.
But for the basic "is composefs enabled at all at runtime"
that is now fully keyed off the config, not the build time
or (worse) whether the deployment happened to have a composefs
blob.
For users who want composefs on, they need to do so in the base
image configuration.
Mary Strodl [Thu, 12 Dec 2024 14:30:59 +0000 (09:30 -0500)]
bin/admin-upgrade: add kexec support
Adds a new `--kexec` flag to `ostree admin upgrade` which will cause
the deployment to be loaded into kexec after the upgrade completes.
It is particularly useful in conjunction with the `--reboot` flag to
perform a reboot into the new deployment without waiting for the
(often slow) firmware initialization to take place. (And in my case,
allows me to avoid a normal reboot, which can be unreliable on my
hardware).
After an image has been loaded (using the `kexec_file_load` syscall),
the `systemctl-reboot` command (which is called when the existing
`-r` flag is included) will trigger a kexec on the loaded image
rather than a normal reboot. From `systemctl(1)`:
If a new kernel has been loaded via kexec --load, a kexec will be
performed instead of a reboot, unless "SYSTEMCTL_SKIP_AUTO_KEXEC=1"
has been set. If a new root file system has been set up on
"/run/nextroot/", a soft-reboot will be performed instead of a
reboot, unless "SYSTEMCTL_SKIP_AUTO_SOFT_REBOOT=1" has been set.
A good in-depth technical explanation of kexec can be found here:
https://web.archive.org/web/20090505132901/http://www.ibm.com/developerworks/linux/library/l-kexec.html
My implementation uses the `kexec_file_load` syscall rather than the
older `kexec_load` syscall, which allows the kernel to verify the
signatures of the new kernel. It is supported on Linux 3.17 and
newer. I assume this probably won't be an issue, but if it is, it's
not that hard to put a preprocessor directive around the kexec stuff
to disable it for older kernels. Even RHEL is new enough now to
not be an issue :)
Colin Walters [Fri, 6 Dec 2024 19:57:19 +0000 (14:57 -0500)]
man: Note semantics combining `root.transient` with `composefs.enabled`
It's all quite confusing having to reason about both the pre-composefs
ostree and the composefs version. But hopefully soon we more firmly
leave behind that first legacy.
Jonathan Lebon [Sat, 14 Dec 2024 13:47:21 +0000 (08:47 -0500)]
lib/deploy: error out if composefs enabled but unsupported
If composefs was explicitly requested (`enabled = true`) but libostree
was not compiled with composefs support, error out at deploy time. This
matches the logic in `ostree-prepare-root`.
Jonathan Lebon [Sat, 14 Dec 2024 13:45:19 +0000 (08:45 -0500)]
libostree/deploy: enable composefs by default
The composefs libostree integration has been supported for a while now
and is actively in use in various ostree/bootc-based systems. Let's
turn it on by default.
This has no effect if composefs support is not compiled in. Note also
that this does not change the default value of the `composefs.enabled`
tristate to `true`. The default is still `maybe`, but the deploy API
will now also create composefs images for `maybe`.
The reason for doing it this way is so that systems upgrading from
old libostree versions (which may either not have composefs support or
may have composefs-related bugs) will still be able to upgrade and not
trip `ostree-prepare-root` in the new deployment (which allows missing
composefs images for `maybe`).
We may in the future change the default value to `true`.
See also: https://github.com/ostreedev/ostree/issues/2867